<template>
	<view class="content">
		<view class="ble-status">
			<text v-if="!isConnect">蓝牙状态：未连接</text>
			<text v-if="isConnect">蓝牙状态：已连接</text>
			<text v-if="connectStatus == 1">连接状态：搜索中</text>
			<text v-if="connectStatus == 2">连接状态：已连接</text>
			<text v-if="connectStatus == -1">连接状态：连接失败</text>
			<text>实时计量：{{number}} {{showUnit}}</text>
			<text>固件版本：{{version}}</text>
			<text>剂量率预警阈值：{{threshold}}</text>
			<text>累计剂量报警阈值：{{accumulatedWarningThreshold}}</text>
			<text>设备ID：{{deviceCode}}</text>
			<text>设备温度：{{temperature}}</text>
		</view>
		<view class="ble-box" v-if="devices.length > 0 && !isConnect">
			<view class="list" v-for="(item, index) in devices" :key="index">
				<text v-text="item.name"></text>
				<button @click="createBLEConnection(item.deviceId)">连接</button>
			</view>
		</view>
		<view class="ble">
			<button type="primary" v-if="!isConnect && connectStatus == 0" @click="initBle">开始搜索</button>
			<button type="primary" v-if="isConnect" @click="closeBLEConnection">断开连接</button>
			<view class="command" v-if="isOperational"> <!--  v-if="isOperational" -->
				<button @click="getFirmwareInfo">获取固件版本</button>
				<button @click="getCurrentDoseRateData">获取当前剂量率数据</button>
				<view class="set">
					<input class="input" v-model="threshold" type="number" placeholder="数字输入框" />
					<button @click="setDoseRateWarningThreshold">设置剂量率预警阈值</button>
				</view>
				<button @click="getContinue">连续获取测量数据</button>
				<button @click="stopContinuouslyObtainingDoseRateData">停止连续获取剂量率数据</button>
				<button @click="setCalibrationParameters">设置校准参数</button>
				<button @click="obtainCalibrationParameters">获取校准参数</button>
				<button @click="getDeviceID">获取设备ID</button>
				<view class="set">
					<input class="input" v-model="deviceCode" maxlength="6" @input="handleInput" type="text"
						placeholder="输入6位,0-9a-zA-Z" />
					<button @click="setDeviceID">设置设备ID</button>
				</view>
				<button @click="setTimeDate">校准日期时间</button>
				<button @click="obtainDeviceTemperatureValue">获取设备温度</button>
				<view class="set">
					<input class="input" v-model="temperatureCalibration" type="number" @input="handleInput2"
						placeholder="数字输入框" />
					<button @click="setTemperatureCalibrationParameters">设置设备校准系统</button>
				</view>
				<button @click="obtainDeviceTemperatureValue">获取校准设备系数</button>
				<view class="set">
					<input class="input" v-model="resistance" type="number" placeholder="数字输入框" />
					<button @click="increaseTheResistanceOfTheDigitalPotentiometer">增加数字电位器电阻</button>
					<button @click="reduceTheResistanceOfDigitalPotentiometers">减少数字电位器电阻</button>
				</view>
				<button @click="obtainDoseRateWarningThreshold">获取剂量率预警阈值</button>
				<view class="set">
					<button @click="setDisplayUnit('00')">设置显示单位(Sv/h)</button>
					<button @click="setDisplayUnit('01')">设置显示单位(Rem/h)</button>
				</view>
				<button @click="getDisplayUnit">获取显示单位</button>
				<view class="set">
					<input class="input" v-model="accumulatedWarningThreshold" type="number" placeholder="数字输入框" />
					<button @click="setDoseRateWarningThreshold">设置剂量率预警阈值</button>
				</view>
				<view class="set">
					<picker @change="bindPickerChange" :value="alarmMethod" :range="alarmMethodArr">
						<view class="uni-input">{{alarmMethodArr[alarmMethod]}}</view>
					</picker>
					<button @click="setDeviceAlarmMode">设置设备报警方式</button>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import * as config from '/config/bleConfig';
	import {
		hexByteLength,
		decToHex,
		addDemoHexBytes,
		hexToBinary,
		hexStringToArrayBuffer,
		ab2hex,
		hexToFloat,
		floatToHex,
		openBluetooth,
		groupStrings,
		stringToHex
	} from '@/util/bleUtil.js';
	export default {
		data() {
			return {
				isConnect: false, // 蓝牙连接状态
				available: false, // 蓝牙适配器是否可用
				discovering: false, // 蓝牙适配器是否处于搜索状态
				connecting: false, // 未连接
				connectStatus: 0, // 0 未连接 1 连接中 2 连接成功 -1 连接失败
				devices: [],
				deviceId: '',
				isOperational: false,
				number: 0, // 剂量数据
				threshold: 5,
				deviceCode: '',
				version: "",
				temperature: "", // 设备温度
				temperatureCalibration: "", // 温度校准系数
				resistance: "",
				showUnit: "Sv/h",
				accumulatedWarningThreshold: "",
				alarmMethod: "00", // 00表示只使能蜂鸣器 01表示只使能振动 02表示蜂鸣器振动全使能 03表示蜂鸣器振动全禁能
				alarmMethodArr: {
					"00": "只使能蜂鸣器",
					"01": "表示只使能振动",
					"02": "蜂鸣器振动全使能",
					"03": "表示蜂鸣器振动全禁能"
				},
			}
		},
		onLoad() {
			let currentDate = new Date();
			let year = currentDate.getFullYear() % 100;
			let moon = currentDate.getMonth() + 1;
			if (moon < 10) {
				moon = '0' + moon;
			}
			let day = currentDate.getDate();
			if (day < 10) {
				day = '0' + day;
			}
			let hours = currentDate.getHours();
			if (hours < 10) {
				hours = '0' + hours;
			}
			let minutes = currentDate.getMinutes();
			let seconds = currentDate.getSeconds();
			if (seconds < 10) {
				seconds = '0' + seconds;
			}
			let week = currentDate.getDay();
			if (week < 10) {
				week = '0' + week;
			}
			let load = year + moon + day + hours + minutes + seconds + week + '08';
			console.log(load)
		},
		methods: {
			/**
			 * 设置设备ID
			 * @param {Object} event
			 */
			handleInput(event) {
				const regex = /^[a-zA-Z0-9]*$/;
				this.inputValue = event.target.value.replace(/[^a-zA-Z0-9]/g, '');
			},

			/**
			 * 设置电阻
			 * @param {Object} event
			 */
			handleInput2(event) {
				let value = event.target.value;
				if (value < 0) {
					this.inputValue = 0;
				} else if (value > 64) {
					this.inputValue = 64;
				}
			},

			bindPickerChange(e) {
				console.log(e)
			},

			/**
			 * 获取固件版本
			 */
			getFirmwareInfo() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.GET_FIRMWARE_VERSION);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 获取当前剂量率数据
			 */
			getCurrentDoseRateData() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.GET_CURR_DOSE_RATE);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 获取每小时的剂量率数据
			 */
			obtainHourlyDoseRateData() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.GET_CURR_HOUR_DOSE_RATE);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 设置剂量率预警阈值
			 */
			setDoseRateWarningThreshold() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.SET_DOSE_RATE_WARNING_THRESHOLD,
					groupStrings(floatToHex(this.threshold)));
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 设置剂量率预警阈值
			 */
			setDoseRateWarningThresholdTwo() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.SET_DOSE_RATE_WARNING_THRESHOLD_TWO,
					groupStrings(floatToHex(this.threshold)));
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 连续获取测量数据
			 */
			getContinue() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.GET_CONTINUOUS_MEASUREMENTS);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 停止连续获取剂量率数据
			 */
			stopContinuouslyObtainingDoseRateData() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.STOP_CONTINUOUS_MEASUREMENTS);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 设置校准参数
			 */
			setCalibrationParameters() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.SET_CALIBRATION_PARAMETERS);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 获取校准参数
			 */
			obtainCalibrationParameters() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.GET_CALIBRATION_PARAMETERS);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 获取设备ID
			 */
			getDeviceID() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.GET_DEVICE_ID);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 设置设备
			 */
			setDeviceID() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.SET_DEVICE_ID, stringToHex(this
					.deviceCode));
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 设置时间和日期
			 */
			setTimeDate() {
				let currentDate = new Date();
				let year = currentDate.getFullYear() % 100;
				let moon = currentDate.getMonth() + 1;
				if (moon < 10) {
					moon = '0' + moon;
				}
				let day = currentDate.getDate();
				if (day < 10) {
					day = '0' + day;
				}
				let hours = currentDate.getHours();
				if (hours < 10) {
					hours = '0' + hours;
				}
				let minutes = currentDate.getMinutes();
				let seconds = currentDate.getSeconds();
				if (seconds < 10) {
					seconds = '0' + seconds;
				}
				let week = currentDate.getDay();
				if (week < 10) {
					week = '0' + week;
				}
				let load = year + moon + day + hours + minutes + seconds + week + '08';
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.GET_DEVICE_TEMPERATURE_VALUE, load);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 获取设备温度值
			 */
			obtainDeviceTemperatureValue() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config
					.SET_TEMPERATURE_CALIBRATION_PARAMETERS);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 设置温度校准参数
			 */
			setTemperatureCalibrationParameters() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config
					.SET_TEMPERATURE_CALIBRATION_PARAMETERS, floatToHex(this.temperatureCalibration));
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 获取校准设备系数
			 */
			obtainCalibrationEquipmentCoefficients() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config
					.GET_TEMPERATURE_CALIBRATION_PARAMETERS);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 增加数字电位器电阻
			 */
			increaseTheResistanceOfTheDigitalPotentiometer() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config
					.ADD_DIGITAL_POTENTIOMETER_RESISTANCE, decToHex(this.resistance, 2));
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 减少数字电位器电阻
			 */
			reduceTheResistanceOfDigitalPotentiometers() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config
					.DEC_DIGITAL_POTENTIOMETER_RESISTANCE, decToHex(this.resistance, 2));
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 获取剂量率预警阈值
			 */
			obtainDoseRateWarningThreshold() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.GET_DOSE_RATE_WARNING_THRESHOLD);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 获取剂量率预警阈值
			 */
			obtainDoseRateWarningThresholdTwo() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.GET_DOSE_RATE_WARNING_THRESHOLD_TWO);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 设置显示单位
			 */
			setDisplayUnit(type) {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.SET_DISPLAY_UNIT, type);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 获取显示单位
			 */
			getDisplayUnit() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.GET_DISPLAY_UNIT);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 设置累计剂量预警阈值
			 */
			setCumulativeDoseWarningThreshold() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config
					.SET_ACCUMULATED_DOSE_WARNING_THRESHOLD, floatToHex(this.accumulatedWarningThreshold));
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 设置累计剂量报警阈值
			 */
			setCumulativeDoseWarningThresholdTwo() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config
					.SET_ACCUMULATED_DOSE_WARNING_THRESHOLD_TWO, floatToHex(this.accumulatedWarningThreshold));
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 获取累计剂量预警阈值
			 */
			getCumulativeDoseWarningThreshold() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config
					.GET_ACCUMULATED_DOSE_WARNING_THRESHOLD);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 获取累计剂量预警阈值
			 */
			getCumulativeDoseWarningThresholdTwo() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config
					.GET_ACCUMULATED_DOSE_WARNING_THRESHOLD_TWO);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 设置设备报警方式
			 */
			setDeviceAlarmMode() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.SET_EQUIPMENT_ALARM_METHOD);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 获取设备报警方式
			 */
			getDeviceAlarmMode() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.GET_EQUIPMENT_ALARM_METHOD);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 设置剂量率预警开关
			 */
			setDoseRateWarningSwitch() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.SET_DOSE_RATE_WARNING_SWITCH);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 获取剂量率预警开关
			 */
			getDoseRateWarningSwitch() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.GET_DOSE_RATE_WARNING_SWITCH);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 设置剂量率报警开关
			 */
			setDoseRateAlarmSwitchTwo() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.SET_DOSE_RATE_WARNING_SWITCH_TWO);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 获取剂量率报警开关
			 */
			getDoseRateAlarmSwitchTwo() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.GET_DOSE_RATE_WARNING_SWITCH_TWO);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 设置累计剂量预警开关
			 */
			setCumulativeDoseWarningSwitch() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.SET_ACCUMULATED_DOSE_WARNING_SWITCH);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 获取累计剂量预警开关
			 */
			getCumulativeDoseWarningSwitch() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.GET_ACCUMULATED_DOSE_WARNING_SWITCH);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 设置累计剂量报警开关
			 */
			setCumulativeDoseWarningSwitchTwo() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config
					.SET_ACCUMULATED_DOSE_WARNING_SWITCH_TWO);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 获取累计剂量报警开关
			 */
			getCumulativeDoseWarningSwitchTwo() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config
					.GET_ACCUMULATED_DOSE_WARNING_SWITCH_TWO);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 数据同步之前询问数据情况
			 */
			inquireAboutDataStatusBeforeDataSynchronization() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config
					.INQUIRE_ABOUT_DATA_STATUS_BEFORE_DATA_SYNCHRONIZATION);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 开始数据同步
			 */
			startDataSynchronization() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.START_DATA_SYNCHRONIZATION);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 恢复出厂设置
			 */
			restoreFactorySettings() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.RESTORE_FACTORY_SETTINGS);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 恢复设备初始状态
			 */
			restoreTheInitialStateOfTheDevice() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config
					.RESTORE_THE_INITIAL_STATE_OF_THE_DEVICE);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 设置累计剂量
			 */
			setCumulativeDose() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config.SET_CUMULATIVE_DOSE);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 访问否允许关屏之状态
			 */
			allowScreenShutdownStatusForAccessOrNot() {
				let command = this.commandBleComposition(config.REQUEST_FRAME, config
					.ALLOW_SCREEN_SHUTDOWN_STATUS_FOR_ACCESS_OR_NOT);
				this.writeBLECharacteristicValue(command);
			},

			/**
			 * 帧组合并执行
			 * 完整的通信帧包括6个部分，分别为帧头、帧长、帧类型、操作码、载荷（数据）、校验和
			 * @param {*} commandType  帧类型 01 请求帧 02 回应帧
			 * @param {*} commandOpcode 操作码
			 * @param {*} commandLoad 荷载默认无
			 */
			commandBleComposition: function(commandType, commandOpcode, commandLoad) {
				// 帧内容 = 帧类型 + 操作码 + 载荷
				var commandContent = commandType + commandOpcode;
				if (commandLoad != null) {
					commandContent += commandLoad;
				}
				// 帧长 = （帧类型 + 操作码 + 载荷）字节长度
				var commandLong = hexByteLength(commandContent);
				// 完成帧
				var command = config.COMMAND_HEAD + commandLong + commandContent + addDemoHexBytes(commandType,
					commandOpcode,
					commandLoad);
				return command;
			},

			/**
			 * 初始化蓝牙模块
			 */
			initBle() {
				let that = this;
				// 先清空所有连接
				this.closeBluetoothAdapter();
				uni.openBluetoothAdapter({
					success(res) {
						console.log(res)
						that.connecting = true;
						that.connectStatus = 1;
						// 监听蓝牙适配器状态变化事件
						that.onBluetoothAdapterStateChange();
						// 初始化完成 开始搜索蓝牙设备
						that.startBluetoothDevicesDiscovery();
					},
					fail(err) {
						if (err.code == 10001) {
							// 蓝牙未打开，打开蓝牙
							openBluetooth()
						} else {
							uni.showToast({
								title: err.errMsg,
								icon: 'error',
								duration: 2000
							});
						}
					}
				})
			},

			/**
			 * 开始搜索蓝牙
			 */
			startBluetoothDevicesDiscovery() {
				let that = this;
				uni.startBluetoothDevicesDiscovery({
					services: [],
					success(res) {
						// 监听蓝牙设备
						that.onBluetoothDeviceFound();
					}
				})
			},

			/**
			 * 停止搜索蓝牙设备
			 */
			stopBluetoothDevicesDiscovery() {
				uni.stopBluetoothDevicesDiscovery({
					success(res) {
						console.log(res)
					}
				})
			},

			/**
			 * 开启监听蓝牙设备
			 */
			onBluetoothDeviceFound() {
				let that = this;
				let devicesArr = this.devices;
				uni.onBluetoothDeviceFound(function(devices) {
					for (let i in devices.devices) {
						if (devices.devices[i].advertisServiceUUIDs[0] == config.BLE_ADVERTISSERVICE_UUID) {
							devicesArr.push(devices.devices[i]);
						}
					}
					that.devices = devicesArr;
				})
			},

			/**
			 * 监听蓝牙适配器状态变化事件
			 */
			onBluetoothAdapterStateChange() {
				uni.onBluetoothAdapterStateChange(function(res) {
					this.available = res.available;
					this.discovering = res.discovering;
				})
			},

			/**
			 * 根据 uuid 获取处于已连接状态的设备
			 */
			getConnectedBluetoothDevices() {
				uni.getConnectedBluetoothDevices({
					success(res) {
						console.log(res)
					}
				})
			},

			/**
			 * 获取在蓝牙模块生效期间所有已发现的蓝牙设备。包括已经和本机处于连接状态的设备。
			 */
			getBluetoothDevices() {
				uni.getBluetoothDevices({
					success(res) {
						console.log(res)
						if (res.devices[0]) {
							console.log(ab2hex(res.devices[0].advertisData))
						}
					}
				})
			},

			/**
			 * 获取本机蓝牙适配器状态。
			 */
			getBluetoothAdapterState() {
				uni.getBluetoothAdapterState({
					success(res) {
						console.log(res)
					}
				})
			},

			/**
			 * 关闭蓝牙模块。调用该方法将断开所有已建立的连接并释放系统资源
			 */
			closeBluetoothAdapter() {
				uni.closeBluetoothAdapter({
					success(res) {
						console.log(res)
					}
				})
			},

			/**
			 * 设置蓝牙最大传输单元
			 */
			setBLEMTU() {
				uni.setBLEMTU({
					deviceId: '',
					mtu: '',
					success(res) {
						console.log(res)
					}
				})
			},

			/**
			 * 向低功耗蓝牙设备特征值中写入二进制数据
			 */
			writeBLECharacteristicValue(value) {
				console.log("writeBLECharacteristicValue value", value)
				let that = this;
				uni.writeBLECharacteristicValue({
					// 这里的 deviceId 需要在 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
					deviceId: that.deviceId,
					// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
					serviceId: config.BLE_SERVICE_UUID,
					// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
					characteristicId: config.BLE_WRITE_CHARACTERISTIC,
					// 这里的value是ArrayBuffer类型
					value: hexStringToArrayBuffer(value),
					success(res) {},
					fail(err) {
						console.log(err)
					}
				})
			},

			/**
			 * 读取低功耗蓝牙设备的特征值的二进制数据值
			 */
			readBLECharacteristicValue() {
				// 必须在这里的回调才能获取
				uni.onBLECharacteristicValueChange(function(characteristic) {
					console.log('characteristic value comed:', characteristic)
				})
				uni.readBLECharacteristicValue({
					// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
					deviceId,
					// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
					serviceId: config.BLE_SERVICE_UUID,
					// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
					characteristicId: config.BLE_NOTIFY_CHARACTERISTIC_UUID,
					success(res) {
						console.log('readBLECharacteristicValue:', res.errCode)
					}
				})
			},

			/**
			 * 监听低功耗蓝牙连接状态的改变事件。包括开发者主动连接或断开连接，设备丢失，连接异常断开等等
			 */
			onBLEConnectionStateChange() {
				let that = this;
				uni.onBLEConnectionStateChange(function(res) {
					console.log(res)
					if (!res.connected) {
						that.initBleData();
					}
					// 该方法回调中可以用于处理连接意外断开等异常情况
				})

			},

			/**
			 * 监听低功耗蓝牙设备的特征值变化事件 必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。
			 */
			onBLECharacteristicValueChange() {
				let that = this;
				uni.onBLECharacteristicValueChange(function(res) {
					// 应答的命令
					let command = ab2hex(res.value);
					// 应答帧长
					let commandLong = command.substring(4, 6);
					// 应答帧操作码
					let commandOpcode = command.substring(8, 10);
					// 应答载荷
					let commandLoad = "";
					console.log(command)
					switch (commandOpcode) {
						case config.GET_FIRMWARE_VERSION: // 获取固件版本号
							commandLoad = command.substring(10, 18);
							that.version = Number((parseInt(groupStrings(commandLoad), 16)) / 100).toFixed(2);
							break;

						case config.GET_CURR_DOSE_RATE: // 获取当前的剂量率数据
							commandLoad = command.substring(10, 18);
							that.number = hexToFloat(groupStrings(commandLoad));
							break;

						case config.GET_CURR_HOUR_DOSE_RATE: // 获取每小时的剂量率数据（暂不用
							commandLoad = command.substring(10, 18);
							that.number = hexToFloat(groupStrings(commandLoad));
							break;

						case config.SET_DOSE_RATE_WARNING_THRESHOLD: // 设置剂量率预警阈值
							commandLoad = command.substring(10, 12);
							if (commandLoad == '01') {
								console.log('设置剂量率预警阈值成功');
							} else {
								console.log('设置剂量率预警阈值失败');
							}
							break;

						case config.SET_DOSE_RATE_WARNING_THRESHOLD_TWO: // 设置剂量率预警阈值
							commandLoad = command.substring(10, 12);
							if (commandLoad == '01') {
								console.log('设置剂量率预警阈值成功');
							} else {
								console.log('设置剂量率预警阈值失败');
							}
							break;

						case config.GET_CONTINUOUS_MEASUREMENTS: // 连续获取测量数据
							commandLoad = command.substring(10, 18);
							that.number = hexToFloat(groupStrings(commandLoad));
							break;

						case config.STOP_CONTINUOUS_MEASUREMENTS: // 停止连续获取剂量率数据
							commandLoad = command.substring(10, 12);
							if (commandLoad == '01') {
								console.log('停止连续获取剂量率数据成功');
							} else {
								console.log('停止连续获取剂量率数据失败');
							}
							break;

						case config.SET_CALIBRATION_PARAMETERS: // 设置校准参数
							commandLoad = command.substring(10, 12);
							if (commandLoad == '01') {
								console.log('设置校准参数成功');
							} else {
								console.log('设置校准参数失败');
							}
							break;

						case config.GET_CALIBRATION_PARAMETERS: // 获取校准参数
							// commandLoad = command.substring(10, 22);
							// that.number = hexToFloat(groupStrings(commandLoad));
							break;

						case config.GET_DEVICE_ID: // 获取设备ID
							commandLoad = command.substring(10, 18);
							that.deviceCode = parseInt(groupStrings(commandLoad), );
							break;

						case config.SET_DEVICE_ID: // 设置设备ID
							commandLoad = command.substring(10, 12);
							if (commandLoad == '01') {
								console.log('设置设备ID成功');
							} else {
								console.log('设置设备ID失败');
							}
							break;

						case config.SET_TIME_DATE: // 设置时间和日期
							commandLoad = command.substring(10, 12);
							if (commandLoad == '01') {
								console.log('设置时间和日期成功');
							} else {
								console.log('设置时间和日期失败');
							}
							break;

						case config.GET_DEVICE_TEMPERATURE_VALUE: // 获取设备温度值
							commandLoad = command.substring(10, 18);
							that.temperature = hexToFloat(groupStrings(commandLoad));
							break;

						case config.SET_TEMPERATURE_CALIBRATION_PARAMETERS: // 设置温度校准参数
							commandLoad = command.substring(10, 12);
							if (commandLoad == '01') {
								console.log('设置温度校准参数成功');
							} else {
								console.log('设置温度校准参数失败');
							}
							break;

						case config.GET_TEMPERATURE_CALIBRATION_PARAMETERS: // 获取温度校准参数
							// commandLoad = command.substring(10, 18);
							// that.temperature = hexToFloat(groupStrings(commandLoad));
							break;

						case config.ADD_DIGITAL_POTENTIOMETER_RESISTANCE: // 增加数字电位器电阻
							commandLoad = command.substring(10, 12);
							if (commandLoad == '01') {
								console.log('增加数字电位器电阻成功');
							} else {
								console.log('增加数字电位器电阻失败');
							}
							break;

						case config.DEC_DIGITAL_POTENTIOMETER_RESISTANCE: // 减少数字电位器电阻
							commandLoad = command.substring(10, 12);
							if (commandLoad == '01') {
								console.log('减少数字电位器电阻成功');
							} else {
								console.log('减少数字电位器电阻失败');
							}
							break;

						case config.GET_DOSE_RATE_WARNING_THRESHOLD: // 获取剂量率预警阈值
							commandLoad = command.substring(10, 18);
							that.threshold = hexToFloat(groupStrings(commandLoad));
							break;

						case config.GET_DOSE_RATE_WARNING_THRESHOLD_TWO: // 获取剂量率预警阈值
							commandLoad = command.substring(10, 18);
							that.threshold = hexToFloat(groupStrings(commandLoad));
							break;

						case config.SET_DISPLAY_UNIT: // 设置显示单位
							commandLoad = command.substring(10, 12);
							if (commandLoad == '01') {
								console.log('设置显示单位成功');
							} else {
								console.log('设置显示单位失败');
							}
							break;

						case config.GET_DISPLAY_UNIT: // 获取显示单位
							commandLoad = command.substring(10, 12);
							if (commandLoad == '01') {
								that.showUnit = "rem/h";
							} else {
								that.showUnit = "Sv/h";
							}
							break;

						case config.SET_ACCUMULATED_DOSE_WARNING_THRESHOLD: // 设置累计剂量预警阈值
							commandLoad = command.substring(10, 12);
							if (commandLoad == '01') {
								console.log('设置累计剂量预警阈值成功');
							} else {
								console.log('设置累计剂量预警阈值失败');
							}
							break;

						case config.SET_ACCUMULATED_DOSE_WARNING_THRESHOLD_TWO: // 设置累计剂量报警阈值
							commandLoad = command.substring(10, 12);
							if (commandLoad == '01') {
								console.log('设置累计剂量预警阈值成功');
							} else {
								console.log('设置累计剂量预警阈值失败');
							}
							break;

						case config.GET_ACCUMULATED_DOSE_WARNING_THRESHOLD: // 获取累计剂量预警阈值
							commandLoad = command.substring(10, 18);
							that.accumulatedWarningThreshold = hexToFloat(groupStrings(commandLoad));
							break;

						case config.GET_ACCUMULATED_DOSE_WARNING_THRESHOLD_TWO: // 获取累计剂量预警阈值
							commandLoad = command.substring(10, 18);
							that.accumulatedWarningThreshold = hexToFloat(groupStrings(commandLoad));
							break;

						case config.SET_EQUIPMENT_ALARM_METHOD: // 设置设备报警方式
							commandLoad = command.substring(10, 18);
							that.number = hexToFloat(groupStrings(commandLoad));
							break;

						case config.GET_EQUIPMENT_ALARM_METHOD: // 获取设备报警方式
							commandLoad = command.substring(10, 18);
							that.number = hexToFloat(groupStrings(commandLoad));
							break;

						case config.SET_DOSE_RATE_WARNING_SWITCH: // 设置剂量率预警开关
							commandLoad = command.substring(10, 18);
							that.number = hexToFloat(groupStrings(commandLoad));
							break;

						case config.GET_DOSE_RATE_WARNING_SWITCH: // 获取剂量率预警开关
							commandLoad = command.substring(10, 18);
							that.number = hexToFloat(groupStrings(commandLoad));
							break;

						case config.SET_DOSE_RATE_WARNING_SWITCH_TWO: // 设置剂量率报警开关
							commandLoad = command.substring(10, 18);
							that.number = hexToFloat(groupStrings(commandLoad));
							break;

						case config.GET_DOSE_RATE_WARNING_SWITCH_TWO: // 获取剂量率报警开关
							commandLoad = command.substring(10, 18);
							that.number = hexToFloat(groupStrings(commandLoad));
							break;

						case config.SET_ACCUMULATED_DOSE_WARNING_SWITCH: // 设置累计剂量预警开关
							commandLoad = command.substring(10, 18);
							that.number = hexToFloat(groupStrings(commandLoad));
							break;

						case config.GET_ACCUMULATED_DOSE_WARNING_SWITCH: // 获取累计剂量预警开关
							commandLoad = command.substring(10, 18);
							that.number = hexToFloat(groupStrings(commandLoad));
							break;

						case config.SET_ACCUMULATED_DOSE_WARNING_SWITCH_TWO: // 设置累计剂量报警开关
							commandLoad = command.substring(10, 18);
							that.number = hexToFloat(groupStrings(commandLoad));
							break;

						case config.GET_ACCUMULATED_DOSE_WARNING_SWITCH_TWO: // 获取累计剂量报警开关
							commandLoad = command.substring(10, 18);
							that.number = hexToFloat(groupStrings(commandLoad));
							break;

						case config.INQUIRE_ABOUT_DATA_STATUS_BEFORE_DATA_SYNCHRONIZATION: // 数据同步之前询问数据情况
							commandLoad = command.substring(10, 18);
							that.number = hexToFloat(groupStrings(commandLoad));
							break;

						case config.START_DATA_SYNCHRONIZATION: // 开始数据同步
							commandLoad = command.substring(10, 18);
							that.number = hexToFloat(groupStrings(commandLoad));
							break;

						case config.GET_ACCUMULATED_DOSE: // 获取累计剂量
							commandLoad = command.substring(10, 18);
							that.number = hexToFloat(groupStrings(commandLoad));
							break;

						case config.RESTORE_FACTORY_SETTINGS: // 恢复出厂设置
							commandLoad = command.substring(10, 18);
							that.number = hexToFloat(groupStrings(commandLoad));
							break;

						case config.RESTORE_THE_INITIAL_STATE_OF_THE_DEVICE: // 恢复设备初始状态
							commandLoad = command.substring(10, 18);
							that.number = hexToFloat(groupStrings(commandLoad));
							break;

						case config.SET_CUMULATIVE_DOSE: // 设置累计剂量
							commandLoad = command.substring(10, 18);
							that.number = hexToFloat(groupStrings(commandLoad));
							break;

						case config.ALLOW_SCREEN_SHUTDOWN_STATUS_FOR_ACCESS_OR_NOT: // 访问否允许关屏之状态
							commandLoad = command.substring(10, 18);
							that.number = hexToFloat(groupStrings(commandLoad));
							break;
					}
				})
			},

			/**
			 * 启用低功耗蓝牙设备特征值变化时的 notify 功能，订阅特征值
			 */
			notifyBLECharacteristicValueChange() {
				let that = this;
				uni.notifyBLECharacteristicValueChange({
					state: true, // 启用 notify 功能
					// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
					deviceId: that.deviceId,
					// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
					serviceId: config.BLE_SERVICE_UUID,
					// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
					characteristicId: config.BLE_NOTIFY_CHARACTERISTIC_UUID,
					success(res) {
						that.onBLECharacteristicValueChange();
						setTimeout(() => {
							that.isOperational = true;
						}, 2000)
					},
					fail(err) {
						console.log('err notifyBLECharacteristicValueChange', err)
					}
				})
			},

			/**
			 * 获取蓝牙设备所有服务(service)。
			 */
			getBLEDeviceServices() {
				let that = this;
				uni.getBLEDeviceServices({
					// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
					deviceId: that.deviceId,
					success(res) {
						that.getBLEDeviceCharacteristics();
					},
					fail(err) {
						if (err.code == 10004) {
							setTimeout(() => {
								that.getBLEDeviceServices();
							}, 500);
						}
						console.log('err getBLEDeviceServices:', err)
					}
				})
			},

			/**
			 *  获取蓝牙设备的信号强度
			 */
			getBLEDeviceRSSI() {
				uni.getBLEDeviceRSSI({
					// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
					deviceId,
					success(res) {
						console.log('device services:', res.services)
					}
				})
			},

			/**
			 * 获取蓝牙设备某个服务中所有特征值
			 */
			getBLEDeviceCharacteristics() {
				let that = this;
				uni.getBLEDeviceCharacteristics({
					// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
					deviceId: that.deviceId,
					// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
					serviceId: config.BLE_SERVICE_UUID,
					success(res) {
						that.notifyBLECharacteristicValueChange();
					},
					fail(err) {
						console.log('err getBLEDeviceCharacteristics:', err)
					}
				})
			},

			/**
			 * 连接低功耗蓝牙设备。
			 * 若APP在之前已有搜索过某个蓝牙设备，并成功建立连接，可直接传入之前搜索获取的 deviceId 直接尝试连接该设备，无需进行搜索操作。
			 */
			createBLEConnection(deviceId) {
				let that = this;
				uni.createBLEConnection({
					// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
					deviceId: deviceId,
					success(res) {
						// 关闭搜索
						that.stopBluetoothDevicesDiscovery();
						// 开启连接监听
						that.onBLEConnectionStateChange();
						// 第一步保存连接ID
						that.deviceId = deviceId;
						that.isConnect = true;
						that.connectStatus = 2;
						// 第二步获取所有服务
						setTimeout(() => {
							that.getBLEDeviceServices();
						}, 1500)
					}
				})
			},

			/**
			 * 断开与低功耗蓝牙设备的连接。
			 */
			closeBLEConnection() {
				let that = this;
				uni.closeBLEConnection({
					deviceId: that.deviceId,
					success(res) {
						that.initBleData();
					}
				})
			},

			/**
			 * 初始化蓝牙数据
			 */
			initBleData() {
				this.isConnect = false;
				this.connecting = false;
				this.connectStatus = 0;
				this.isOperational = false;
				this.devices = [];
				this.deviceId = '';
				this.$forceUpdate();
			}
		}
	}
</script>

<style lang="scss" scoped>
	.content {
		display: flex;
		flex-flow: column;
		align-items: center;
		justify-content: center;

		.ble-status {
			width: 100%;
			display: flex;
			flex-flow: column;
			padding-left: 30px;
		}

		.ble {
			width: 100%;
			margin-top: 200px;
			display: flex;
			justify-content: start;
			flex-flow: column;
			gap: 10px;

			button {
				margin: 0;
			}

			.command {
				width: 100%;
				display: flex;
				flex-flow: column;
				justify-content: center;
				align-items: center;

				.set {
					width: 100%;
					display: flex;
					align-items: center;
					justify-content: center;

					.input {
						width: 150px;
						height: 45px;
						border: 1px solid #ddd;
						padding-left: 10px
					}
				}
			}
		}

		.ble-box {
			width: 100%;
			margin-top: 30px;
			border-top: 1px solid #ddd;

			.list {
				width: 100%;
				height: 40px;
				display: flex;
				justify-content: space-between;
				align-items: center;
			}
		}
	}
</style>